package Majisuka
{
	import com.sina.microblog.utils.StringEncoders;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.Shape;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.utils.getDefinitionByName;
	
	import mx.charts.BubbleChart;
	import mx.controls.Button;
	
	import spark.components.BorderContainer;

	public class Game
	{
		private var pidUsed:int ;
		private var gameName:String ;
		public var people:Vector.<People> ;
		public var places:Vector.<Place> ;
		public var groups:Vector.<Group> ;
		private var xListGroups:XMLList ;
		private var _groupCount:int ;
		private var _player:int ; // Which group does the player play?
		private var _background:String ;
		private var _backgroundImage:Bitmap ;
		
		public function Game()
		{
			people = new Vector.<People> ;
			places = new Vector.<Place> ;
			groups = new Vector.<Group> ;
			_backgroundImage = null ;
			gameName = "" ;
		}

		public function get backgroundImage():Bitmap
		{
			return _backgroundImage;
		}

		public function set backgroundImage(value:Bitmap):void
		{
			_backgroundImage = value;
		}

		public function get player():int
		{
			return _player;
		}

		public function set player(value:int):void
		{
			_player = value;
		}

		public function get groupCount():int
		{
			return _groupCount;
		}

		public function set groupCount(value:int):void
		{
			_groupCount = value;
		}

		public function init():void
		{
		}
		
		public function AddFriend( pe:People ):Boolean
		{
			var len:int ;
			var i:int ;
			
			// Find a place for the people
			len = places.length ;
			for ( i = 0 ; i < len ; ++i )
			{
				if ( places[i].owner == player )
					break ;
			}
			
			// Other information
			pe.id = people.length ;
			pe.currHp = pe.hp ;
			pe.where = i ;
			pe.group = player ;
			
			// Test whether this friend is already in the game
			len = people.length ;
			for ( i = 0 ; i < len ; ++i )
			{
				if ( people[i].sinaId == pe.sinaId )
					return false ;
			}
			
			people.push( pe ) ;
			return true ;
		}
		
		public function LoadGame( game:String, playerGroup:String = null):void
		{
			var file:File ;
			var fp:FileStream ;
			var x:XML ;
			var i:int ;
			var cnt:int ;
			var p:People ;
			var tmpPlace:Place ;
			var tmpGroup:Group ;
			var xList:XMLList ;
			
			gameName = game ;

			file = File.applicationDirectory.resolvePath( "profile\\" + game + ".xml" ) ;
			fp = new FileStream() ;
			fp.open( file, FileMode.READ ) ;
			
			x = new XML( fp.readUTFBytes( fp.bytesAvailable ) ) ;
			
			// Read in game's data
			if ( playerGroup == null ) // From load game
				_player = int(x.game.player) ;
			else // From create new game
				_player = int( playerGroup ) ;
			
			_background = x.game.background ;
			
			// Read in people's data
			xList = x.people ;
			cnt = xList.length();
			for ( i = 0 ; i < cnt ; ++i )
			{
				p = new People() ;
				p.Load( i, xList[i] ) ;
				people.push( p ) ;
			}
			
			// Read in places' data
			xList = x.place ;
			cnt = xList.length() ;
			for ( i = 0 ; i < cnt ; ++i )
			{
				tmpPlace = new Place() ;
				tmpPlace.Load( i, xList[i] ) ;
				places.push( tmpPlace ) ;
			}
			
			xListGroups = x.group ;
			_groupCount = xListGroups.length() ; 
			
			for ( i = 0 ; i < _groupCount ; ++i )
			{
				tmpGroup = new Group() ;
				tmpGroup.id = i ;
				groups.push( tmpGroup ) ;
			}
			
			fp.close() ;
			
			// Load background image
			var loader:Loader = new Loader() ;
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, OnLoadImageComplete ) ;
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, OnLoadImageComplete ) ;
			loader.load( new URLRequest( "image\\" + _background ) ) ;
		}
		
		public function OnLoadImageComplete( evt:Event ):void
		{
			_backgroundImage = new Bitmap() ;
			var data:BitmapData = evt.target.content.bitmapData ;
			_backgroundImage.bitmapData = data ;
		}
		
		public function OnLoadImageError( evt:ErrorEvent ):void
		{
			_backgroundImage = new Bitmap() ;
			var data:BitmapData = new BitmapData( 100, 100, false, 0xffffff ) ;
			_backgroundImage.bitmapData = data ;
		}		
		
		public function GetBackground( width:int, height:int, alpha:Number = 1.0 ):Bitmap
		{
			_backgroundImage.width = width ;
			_backgroundImage.height = height ;
			_backgroundImage.alpha = alpha ;
			return _backgroundImage ;
		}
		
		public function Save():void
		{
			var file:File ;
			var fp:FileStream ;
			var x:XML = <body></body> ;
			var i:int ;
			var len:int ;
			
			file = new File( File.applicationDirectory.resolvePath( 
						"profile\\" + gameName+".xml" ).nativePath );
			fp = new FileStream() ;
			fp.open( file, FileMode.WRITE ) ;
			
			// Output the game data
			var gamex:XML = 
				<game>
					<player>{_player}</player>
					<background>{_background}</background>
				</game> ;
			x.appendChild( gamex ) ;
			
			// Save the people
			len = people.length ;
			for ( i = 0 ; i < len ; ++i )
				x.appendChild( people[i].Save() ) ;
			
			// Save the places
			len = places.length ;
			for ( i = 0 ; i < len ; ++i )
				x.appendChild( places[i].Save() ) ;
			x.appendChild( xListGroups ) ;
			fp.writeUTFBytes( x.toXMLString() ) ;
			fp.close() ;
		}
		
		public function Rest( g:int ):void
		{
			// Group g's people rests
			var i:int ;
			var len:int ;
			
			len = people.length ;
			for ( i = 0 ; i < len ; ++i )
			{
				if ( people[i].group == g )
					people[i].RestoreHp( 10 ) ;
			}
		}
		
		public function AIMove( from:int, to:int ):void
		{
			// Move people from place from to to by AI
			var i:int ;
			var len:int ;
			
			len = people.length ;
			for ( i = 0 ; i < len ; ++i )
			{
				if ( people[i].where == from && people[i].hp > 0 
					&& Math.random() < 0.3 )
				{
					people[i].Fatigue( 10 ) ;
					people[i].where = to ;
				}
			}
		}
		
		public function AICanWinBattle( from:int, to:int ):Boolean
		{
			var i:int ;
			var k:int ;
			var len:int ;
			var fPeople:Vector.<int> = new Vector.<int> ;
			var tPeople:Vector.<int> = new Vector.<int> ;
			var fAbility:Number = 0 ;
			var tAbility:Number = 0 ;
			
			len = people.length ;
			for ( i = 0 ; i < len ; ++i )
			{
				if ( people[i].currHp == 0 )
					continue ;
				if ( people[i].where == from )
					fPeople.push( i ) ;
				else if ( people[i].where == to )
					tPeople.push( i ) ;
			}		
			
			len = fPeople.length ;
			for ( i = 0 ; i < len ; ++i )
			{
				k = fPeople[i] ;
				fAbility = fAbility + people[k].att + people[k].def + people[k].currHp ;
			}
			
			len = tPeople.length ;
			for ( i = 0 ; i < len ; ++i )
			{
				k = tPeople[i] ;
				tAbility = tAbility + people[k].att + people[k].def + people[k].currHp ;
			}
			return fAbility > tAbility ;
		}
	}
}